import Emitter from 'tiny-emitter';

export default class BaseModel extends Emitter {
  constructor() {
    super();
  }

  tweenGroup = new TWEEN.Group();
  tweenList = [];
  listener = {};
  object = new THREE.Group();
  disposed = false;

  #delegatingHandler(fn) {
    return (...args) => {
      if (!this.disposed) {
        fn(...args);
      }
    };
  }

  dispose() {
    this.tweenGroup = null;
    this.tweenList = null;
    this.listener = null;
    this.object = null;
    this.disposed = true;
  }

  #listenFn = this.#delegatingHandler((obj, name, handler) => {
    this.listener[name] ??= [];
    this.listener[name].push([obj, handler]);
  });

  listen(...args) {
    this.#listenFn(...args);
  }

  #tickFn = this.#delegatingHandler((time) => {
    this.tweenGroup?.update(time);
  });

  tick(...args) {
    this.#tickFn(...args);
  }

  #startFn = this.#delegatingHandler(() => {
    this.tweenList.forEach((tween) => {
      tween.start();
    });
  });

  start() {
    this.#startFn();
  }

  #stopFn = this.#delegatingHandler(() => {
    this.tweenList.forEach((tween) => {
      tween.stop();
    });
  });

  stop() {
    this.#stopFn();
  }
}
